<?php
/**
 * 该类定义了一些用户简化文件系统操作的函数
 * 
 */
class Helper_FileSystem{
	/**
	 * 创建一个目录树
	 *
	 * 用法：
	 * <code>
	 * mkdirs('/top/second/3rd');
	 * </code>
	 *
	 * @param string $dir
	 * @param int $mode
	 */
	function mkdirs($dir, $mode = 0777)
	{
	    if (!is_dir($dir)) {
	        mkdirs(dirname($dir), $mode);
	        return mkdir($dir, $mode);
	    }
	    return true;
	}
	
	/**
	 * 删除指定目录及其下的所有文件和子目录
	 *
	 * 用法：
	 * <code>
	 * // 删除 my_dir 目录及其下的所有文件和子目录
	 * rmdirs('/path/to/my_dir');
	 * </code>
	 * 注意：使用该函数要非常非常小心，避免意外删除重要文件。
	 *
	 * @param string $dir
	 */
	function rmdirs($dir)
	{
	    $dir = realpath($dir);
	    if ($dir == '' || $dir == '/' ||
	        (strlen($dir) == 3 && substr($dir, 1) == ':\\'))
	    {
	        // 禁止删除根目录
	        return false;
	    }
	
	    // 遍历目录，删除所有文件和子目录
	    if(false !== ($dh = opendir($dir))) {
	        while(false !== ($file = readdir($dh))) {
	            if($file == '.' || $file == '..') { continue; }
	            $path = $dir . DIRECTORY_SEPARATOR . $file;
	            if (is_dir($path)) {
	                if (!rmdirs($path)) { return false; }
	            } else {
	                unlink($path);
	            }
	        }
	        closedir($dh);
	        rmdir($dir);
	        return true;
	    } else {
	        return false;
	    }
	}
	/**
	 * rm() -- Vigorously erase files and directories.
	 * 
	 * @param $fileglob mixed If string, must be a file name (foo.txt), glob pattern (*.txt), or directory name.
	 *                        If array, must be an array of file names, glob patterns, or directories.
	 */
	function rm($fileglob)
	{
	    if (is_string($fileglob)) {
			if (is_dir($fileglob)) {
	            $ok = self::rm("$fileglob/*");
	            if (! $ok) {
	                return false;
	            }
	            return rmdir($fileglob);
	        } else {
	            $matching = glob($fileglob);
	            if ($matching === false) {
	                trigger_error(sprintf('No files match supplied glob %s', $fileglob), E_USER_WARNING);
	                return false;
	            } 
	            foreach ($matching as $filename){
	            	if (is_file($filename)) {
	            		$rcs[] = unlink($filename);
	            	} else{
	            		$rcs[] = self::rm($filename);
	            	}
	            }
	            if (in_array(false, $rcs)) {
	                return false;
	            }
	        }
	    } else if (is_array($fileglob)) {
	    	
            foreach ($fileglob as $filename){
            	$rcs[] = self::rm($filename);
            }
	        if (in_array(false, $rcs)) {
	            return false;
	        }
	    } else {
	        trigger_error('Param #1 must be filename or glob pattern, or array of filenames or glob patterns', E_USER_ERROR);
	        return false;
	    }
	
	    return true;
	}
	
	/**
	 * 递归读出目录结构
	 *
	 * @param string $dir
	 * @return array
	 */
	static function readDirTree($dir) {
	   $array = array();
	   $d = dir($dir);
	   while (false !== ($entry = $d->read())) {
	       if($entry!='.' && $entry!='..') {
	       	   $fname =  $entry;
	           $entry = $dir.'/'.$entry;
	           if(is_dir($entry)) {
	               $array[$fname] = $entry;
	               $array = array_merge($array,self::readDirTree($entry));
	           } else {
	               $array[$fname] = $entry;
	           }
	       }
	   }
	   $d->close();
	   return $array;
	}
}
